package com.baseproject.volley;


import com.baseproject.util.LogUtils;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Created by hp on 2017/3/28.
 */

public class ThreadPoolManager {
    private static ThreadPoolManager instance = null;

    /**
     * 线程池 执行请求
     */
    private ThreadPoolExecutor threadPoolExecutor;

    private LinkedBlockingQueue<Future<?>> service = new LinkedBlockingQueue<>();

    public static ThreadPoolManager getInstance() {
        if (null == instance) {
            synchronized (ThreadPoolManager.class) {
                if (null == instance) {
                    instance = new ThreadPoolManager();
                }
            }
        }
        return instance;
    }

    private ThreadPoolManager() {
        threadPoolExecutor = new ThreadPoolExecutor(4, 10, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(4), handler);
        //开启请求队列
        threadPoolExecutor.execute(runnable);
    }

    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            while (true) {
                FutureTask futureTask = null;
                try { //取一个请求 去执行 阻塞式
                    futureTask = (FutureTask) service.take();
                } catch (InterruptedException e) {
                    LogUtils.logCatchedException(e);
                    e.printStackTrace();
                }
                if (null != futureTask) {//拿到请求，添加到线程池
                    threadPoolExecutor.execute(futureTask);
                }
            }
        }
    };

    /**
     * 暴露api给外部添加请求
     * @param futureTask
     * @param <T>
     */
    public <T> void execute(FutureTask<T> futureTask) {
        if(null != futureTask) {
            try {//添加请求到队列
                service.put(futureTask);
            } catch (InterruptedException e) {
                LogUtils.logCatchedException(e);
                e.printStackTrace();
            }
        }
    }

    /**
     * 拒绝策略
     */
    private RejectedExecutionHandler handler = new RejectedExecutionHandler() {
        @Override
        public void rejectedExecution(Runnable runnable, ThreadPoolExecutor executor) {
            try {
                service.put(new FutureTask<Object>(runnable, null));
            } catch (InterruptedException e) {
                LogUtils.logCatchedException(e);
                e.printStackTrace();
            }
        }
    };


}
